﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Xml;
using System.IO;

public struct GameMusicInfo
{
    public string sGameBackGroundMusic { get; set; }
    public string sStartMainBackGroundMusic { get; set; }
    public string sFallBallSound { get; set; }
    public string sFlyBirdSound { get; set; }


    public GameMusicInfo(string sGameBackGroundMusic, string sStartMainBackGroundMusic, string sFallBallSound, string sFlyBirdSound)
    {
        this.sGameBackGroundMusic = sGameBackGroundMusic;
        this.sStartMainBackGroundMusic = sStartMainBackGroundMusic;
        this.sFallBallSound = sFallBallSound;
        this.sFlyBirdSound = sFlyBirdSound;
    }
    public void SetValue(string sGameBackGroundMusic, string sStartMainBackGroundMusic, string sFallBallSound, string sFlyBirdSound)
    {
        this.sGameBackGroundMusic = sGameBackGroundMusic;
        this.sStartMainBackGroundMusic = sStartMainBackGroundMusic;
        this.sFallBallSound = sFallBallSound;
        this.sFlyBirdSound = sFlyBirdSound;
    }
}

public struct GameImageInfo
{
    public string sGameBackGroundImage { get; set; }
    public string sFallBallImage { get; set; }
    public string sFlyBirdImage { get; set; }
    public GameImageInfo(string sGameBackGroundImage, string sFallBallImage, string sFlyBirdImage)
    {
        this.sGameBackGroundImage = sGameBackGroundImage;
        this.sFallBallImage = sFallBallImage;
        this.sFlyBirdImage = sFlyBirdImage;
    }
    public void SetValue(string sGameBackGroundImage, string sFallBallImage, string sFlyBirdImage)
    {
        this.sGameBackGroundImage = sGameBackGroundImage;
        this.sFallBallImage = sFallBallImage;
        this.sFlyBirdImage = sFlyBirdImage;
    }
}

public struct StairPropertyInfo
{
    public int iStage { get; set; }//关卡数，第1关：1-Gamedata.pi.层数
    public GameImageInfo gii;//图片信息
    public GameMusicInfo gmi;//音乐信息
    public StairGeneralRate sgr;//关卡的难度系数
    public StairPropertyInfo(int iStage, GameImageInfo gii, GameMusicInfo gmi, StairGeneralRate sgr)
    {
        this.iStage = iStage;
        this.gii = gii; 
        this.gmi = gmi;
        this.sgr = sgr;
    }
    public void SetValue(int iStage, GameImageInfo gii, GameMusicInfo gmi, StairGeneralRate sgr)
    {
        this.iStage = iStage;
        this.gii = gii;
        this.gmi = gmi;
        this.sgr = sgr;
    }
}


public struct StairGeneralRate
{
    public float fFallingStair1Rate { get; set; } //计时梯1
    public float fFallingStair2Rate { get; set; } //计时梯2
    public float fFireStairRate { get; set; } //火梯
    public float fQuestionStairRage { get; set; } //分叉梯
    public float fQuestionStair3Rage { get; set; }//分叉梯中3梯的比例
    public FallBallProp fbpFallBall;
    public float fEnegyGeneralRate { get; set; }
    public float fGameSpeed { get; set; }
    public StairGeneralRate(float fFallingStair1Rate, float fFallingStair2Rate,
        float fFireStairRate, float fQuestionStairRage, float fQuestionStair3Rage, FallBallProp fbpFallBall,
        float fEnegyGeneralRate, float fGameSpeed)
    {
        this.fFallingStair1Rate = fFallingStair1Rate;
        this.fFallingStair2Rate = fFallingStair2Rate;
        this.fFireStairRate = fFireStairRate;
        this.fQuestionStairRage = fQuestionStairRage;
        this.fQuestionStair3Rage = fQuestionStair3Rage;
        this.fbpFallBall = fbpFallBall;
        this.fEnegyGeneralRate = fEnegyGeneralRate;
        this.fGameSpeed = fGameSpeed;
    }

    public void SetValue(float fFallingStair1Rate, float fFallingStair2Rate,
        float fFireStairRate, float fQuestionStairRage, float fQuestionStair3Rage, FallBallProp fbpFallBall,
        float fEnegyGeneralRate, float fGameSpeed)
    {
        this.fFallingStair1Rate = fFallingStair1Rate;
        this.fFallingStair2Rate = fFallingStair2Rate;
        this.fFireStairRate = fFireStairRate;
        this.fQuestionStairRage = fQuestionStairRage;
        this.fQuestionStair3Rage = fQuestionStair3Rage;
        this.fbpFallBall = fbpFallBall;
        this.fEnegyGeneralRate = fEnegyGeneralRate;
        this.fGameSpeed = fGameSpeed;

    }
}

/*
public struct StageInfo
{
    public string sFallBall { get; set; }
    public string sFallBall2 { get; set; }
    public string sFlyBird { get; set; }
    public string sFollowUp { get; set; }

    public StageInfo(string sFallBall, string sFallBall2, string sFlyBird, string sFollowUp)
    {
        this.sFallBall = sFallBall;
        this.sFallBall2 = sFallBall2;
        this.sFlyBird = sFlyBird;
        this.sFollowUp = sFollowUp;
    }
    public void SetValue(string sFallBall, string sFallBall2, string sFlyBird, string sFollowUp)
    {
        this.sFallBall = sFallBall;
        this.sFallBall2 = sFallBall2;
        this.sFlyBird = sFlyBird;
        this.sFollowUp = sFollowUp;
    }
}

 */

public struct PlayerInfo
{
    public GameObject gPlayer { get; set; }//玩家对象
    public GameObject pPlayer { get; set; }//玩家类
    public int iLife { get; set; }//玩家体力
    public int iLifeSetting { get; set; }//玩家体力
    public int iChar { get; set; }//玩家角色
    public float fYAxisFix { get; set; }//玩家Y轴偏移
    public float fZAxisFix { get; set; }//玩家Z轴偏移
    public float fJumpV { get; set; }//跳跃过程的速度
    public float fJumpDist { get; set; }//跳跃的高度
    public int iEnegyNum { get; set; }//当前能量数
    public int iPlayerStatus { get; set; } //玩家状态 0：正常  1：无敌  2：飞行
    public void SetValue(GameObject gPlayer, GameObject pPlayer, int iLife, int iLifeSetting,int iChar, float fYAxisFix,
        float fZAxisFix, float fJumpV, float fJumpDist, int iEnegyNum, int iPlayerStatus)
    {
        this.gPlayer = gPlayer;
        this.pPlayer = pPlayer;
        this.iLife = iLife;
        this.iLifeSetting = iLifeSetting;
        this.iChar = iChar;
        this.fYAxisFix = fYAxisFix;
        this.fZAxisFix = fZAxisFix;
        this.fJumpV = fJumpV;
        this.fJumpDist = fJumpDist;
        this.iEnegyNum = iEnegyNum;
        this.iPlayerStatus = iPlayerStatus;
    }
}

public struct GameInfo
{
    public Vector3 vBirthPoint { get; set; }//首个stair位置
    public float fHorzValue { get; set; }//水平间隔
    public float fVertValue { get; set; }//竖直间隔
    public int iStairNumPassed { get; set; }//过关stair数
    public float fHorzMaxBound { get; set; }//水平边界
    public bool bIsGameRunning { get; set; }//是否游戏运行，当角色死亡、看问题、过关、预览等时，游戏处于暂停状态
    public float fZAxisPlane { get; set; }//平台Z轴偏移
    public int iTurnStartFloor { get; set; }//起始层
    public StairGeneralRate SGR;
    public float fMsgBoxAutoCloseSec { get; set; }//框自动关闭时间
    public bool bIsGameMode { get; set; } //游戏模式为TRUE，练习模式为FALSE
    public float fZAxisStair { get; set; }//STAIR轴偏移
    public int iEnegyNumMax { get; set; }//能量数最大值
    public int iEnegyPermax { get; set; }//每个能量最大值
    public float fGameSpeed { get; set; }//游戏速度，关系到计时，落石、计时梯等

    public void SetValue(Vector3 vBirthPoint,float fHorzValue,float fVertValue,int iStairNumPassed,
        float fHorzMaxBound, bool bIsGameRunning, float fZAxisPlane, int iTurnStartFloor, StairGeneralRate SGR,
        float fMsgBoxAutoCloseSec, bool bIsGameMode, float fZAxisStair, int iEnegyNumMax, int iEnegyPermax, float fGameSpeed)
    {
        this.vBirthPoint = vBirthPoint;
        this.fHorzValue = fHorzValue;
        this.fVertValue = fVertValue;
        this.iStairNumPassed = iStairNumPassed;
        this.fHorzMaxBound = fHorzMaxBound;
        this.bIsGameRunning = bIsGameRunning;
        this.fZAxisPlane = fZAxisPlane;
        this.iTurnStartFloor = iTurnStartFloor;
        this.SGR = SGR;
        this.fMsgBoxAutoCloseSec = fMsgBoxAutoCloseSec;
        this.bIsGameMode = bIsGameMode;
        this.fZAxisStair = fZAxisStair;
        this.iEnegyNumMax = iEnegyNumMax;
        this.iEnegyPermax = iEnegyPermax;
        this.fGameSpeed = fGameSpeed;
    }
}

public struct CameraInfo
{
    public float fYAxisFix { get; set; }
    public float fZAxisFix { get; set; }
    public void SetValue(float fYAxisFix,float fZAxisFix)
    {
        this.fYAxisFix = fYAxisFix;
        this.fZAxisFix = fZAxisFix;
    }
}

public struct QuestionInfo
{
    public List<questions> LstQuestions;    
    public void SetValue(List<questions> LstQuestions)
    {
        this.LstQuestions = LstQuestions;
    }
}

public struct InterfaceInfo
{
    public Vector3 vBtnClicked { get; set; }
    public Vector3 vBtnNormal { get; set; }
    public void SetValue(Vector3 vBtnClicked, Vector3 vBtnNormal)
    {
        this.vBtnClicked = vBtnClicked;
        this.vBtnNormal = vBtnNormal;
    }
}

public struct FallBallInfo
{
    public float fFallBallV { get; set; }//普通下降速度
    public float fFallBall2V { get; set; }//斜向下降速度
    public float fFallBall2Range { get; set; }//斜向范围 -90~90度内
    public float fFlyBirdRange { get; set; }//纵向斜角 
    public float fFlyBirdV { get; set; }//飞鸟速度
    public void SetValue(float fFallBallV, float fFallBall2V, float fFallBall2Range, float fFlyBirdRange, float fFlyBirdV)
    {
        this.fFallBallV = fFallBallV;
        this.fFallBall2V = fFallBall2V;
        this.fFallBall2Range = fFallBall2Range;
        this.fFlyBirdRange = fFlyBirdRange;
        this.fFlyBirdV = fFlyBirdV;
    }
}



public struct FallBallProp
{
    public bool bIsFalling { get; set; }
    public float fFallBallTime { get; set; }//火球产生间隔
    public float tFallBallTimeRandom { get; set; }//间隔随机值比例
    public float fFallBall2Rage { get; set; }//斜向火球比例
    public bool bIsFlyBird { get; set; } //飞鸟
    public float fFlyBirdTime { get; set; }//飞鸟产生间隔
    public float tFlyBirdTimeRandom { get; set; }//飞鸟随机值比例 
    public FallBallProp(bool bIsFalling, float fFallBallTime, float tFallBallTimeRandom, float fFallBall2Rage,
        bool bIsFlyBird, float fFlyBirdTime, float tFlyBirdTimeRandom)
    {
        this.bIsFalling = bIsFalling;
        this.fFallBallTime = fFallBallTime;
        this.tFallBallTimeRandom = tFallBallTimeRandom;
        this.fFallBall2Rage = fFallBall2Rage;
        this.bIsFlyBird = bIsFlyBird;
        this.fFlyBirdTime = fFlyBirdTime;
        this.tFlyBirdTimeRandom = tFlyBirdTimeRandom;
    }
}


public class GameData  
{
    public static GameInfo gi;
    public static PlayerInfo pi;
    public static CameraInfo ci;
    public static QuestionInfo qi;
    public static FallBallInfo fbi;
    public static Hashtable htAudio;
    public static InterfaceInfo ii;
    public static List<StairPropertyInfo> lstSPI;
    public static StairPropertyInfo spi;
    public static GameMusicInfo gmi;
    public static GameImageInfo gii;
    /// <summary>
    /// 
    /// </summary>

    public static void InitialGameData()
    {
        CommonFunctionA.Initial();
        pi = new PlayerInfo();
        pi.SetValue(null, null, 10, 10,0, 0.65f, -0.04f, 5, 0.18f, 0,0);
        ii = new InterfaceInfo();
        ii.SetValue(new Vector3(1.1f, 1.1f, 1.1f), new Vector3(1, 1, 1));
        gi = new GameInfo();
        gi.SetValue(new Vector3(0, 0, -0.03f), 1, 1, 30, 10f, false, -0.02f, 0, new StairGeneralRate(), 3, true, -0.03f, 20, 5,1f);
        ci = new CameraInfo();
        ci.SetValue(0.5f, -10f);
        qi = new QuestionInfo();
        GeneralQuestion(10);
        fbi = new FallBallInfo();
        fbi.SetValue(1f, 0.8f, 30f,5f,0.8f);
        lstSPI = new List<StairPropertyInfo>();
        spi = new StairPropertyInfo();
        
        //第0-2关
        /*
        si = new StageInfo("GameFB_00", "GameFB2_00", "GameBD_00", "GameFR_00");
        gii = new GameImageInfo("GameBG_00", "GameFB_00", "GameBD_00");
        gmi = new GameMusicInfo("GameBGM_00","StartMain","GameFBM_00","GameBirdSound_00");
        StairGeneralRate sgr =new StairGeneralRate(0.2f, 0.2f, 0.2f, 0.1f, 0.5f, new FallBallProp(true, 5, 1f, 0.5f,true,5,1), 1f,0.5f);
        lstSPI.Add(new StairPropertyInfo(0, gii, gmi,sgr,si));
        lstSPI.Add(new StairPropertyInfo(1, gii, gmi, sgr, si));
        lstSPI.Add(new StairPropertyInfo(2, gii, gmi, sgr, si));

        //第3-5关
        si = new StageInfo("GameFB_01", "GameFB2_01", "GameBD_01", "GameFR_01");
        gii = new GameImageInfo("GameBG_01", "GameFB_01", "GameBD_01");
        gmi = new GameMusicInfo("GameBGM_01", "StartMain", "GameFBM_01", "GameBirdSound_01");
        lstSPI.Add(new StairPropertyInfo(3, gii, gmi, sgr, si));
        lstSPI.Add(new StairPropertyInfo(4, gii, gmi, sgr, si));
        lstSPI.Add(new StairPropertyInfo(5, gii, gmi, sgr, si));
        for (int i = 6; i < 100; i++)
        {
            lstSPI.Add(new StairPropertyInfo(i, gii, gmi, sgr, si));
        }
        */
        //StairGeneralRate sgr = new StairGeneralRate(0.2f, 0.2f, 0.2f, 0.1f, 0.5f, new FallBallProp(true, 5, 1f, 0.5f, true, 5, 1), 1f, 0.5f);
        
        
        for (int j = 0; j < 20 * 3; j++)
        {
            int i = (int)(j / 3);
            i = (int)(i % 5);
            gii = new GameImageInfo("GameBG_0" + i, "GameFB_0" + i, "GameBD_0" + i);
            gmi = new GameMusicInfo("GameBGM_0" + i, "StartMain", "GameFBM_0" + i, "GameBirdSound_0" + i);
            StairGeneralRate sgr = new StairGeneralRate
                (
                j * 0.03f > 0.25f ? 0.15f : j * 0.03f, //计时梯1  不超过15%
                j>=2?(j * 0.025f > 0.3f ? 0.2f : j * 0.025f):0, //计时梯2   20%
                j>=3?(j * 0.02f > 0.25f ? 0.25f : j * 0.02f):0, //火梯
                j>=4?(j * 0.025f > 0.2f ? 0.2f : j * 0.025f):0, //分支梯
                j * 0.05f, //3分支
                new FallBallProp(
                    j > 2 ? true : false, //有火球
                    8 - j * 0.5f < 3 ? 3 : 8 - j * 0.5f,    //火球掉落时间间隔
                    1f,   //上述随机偏移
                    j * 0.1f >0.8f?0.8f:j*0.1f, //斜向火球概率
                    j > 3 ? true : false, //有飞鸟
                    10 - j * 0.5f < 3 ? 3 : 8 - j * 0.5f,    //飞鸟间隔
                    1f),   //上述随机偏移
               0.3f,   // 能量概率
               0.5f + j * 0.03>1.5f? 1.5f:0.5f+j*0.03f  // 游戏速度
               );
            lstSPI.Add(new StairPropertyInfo(j, gii, gmi, sgr));
        }
        
    }


    private static GameData m_instance;

    public static GameData GetInstance()
    {
        if (m_instance == null)
        {
            m_instance = new GameData();
            InitialGameData();
        }
        return m_instance;
    }
    

    /*
    public static List<string> ReadXml(string sFileName, int Id, string sName)
    {
        XmlDocument xml = new XmlDocument();
        XmlReaderSettings set = new XmlReaderSettings();
        set.IgnoreComments = true;//这个设置是忽略xml注释文档的影响。有时候注释会影响到xml的读取
        string sPath = Application.dataPath + "/Resources/"+sFileName;
        xml.Load(XmlReader.Create(sPath, set));
        XmlNodeList xmlNodeList = xml.SelectSingleNode("objects").ChildNodes;
        string sContent = "";
        List<string> lstContent = new List<string>();
        foreach (XmlElement xl1 in xmlNodeList)
        {
            if (xl1.GetAttribute("id") == Id.ToString())
            {
                foreach (XmlElement xl2 in xl1.ChildNodes)
                {
                    if (xl2.GetAttribute("name") == sName)
                    {
                        lstContent.Add(xl2.InnerText);
                        sContent = xl2.InnerText;
                    }
                }
            }
        }
        return lstContent;
    }

    public static void WriteXml(string sFileName, int Id, string sName, string sContent)
    {
        string path = Application.dataPath + "/Resources/" + sFileName;
        if (File.Exists(path))
        {
            XmlDocument xml = new XmlDocument();
            xml.Load(path);
            XmlNodeList xmlNodeList = xml.SelectSingleNode("objects").ChildNodes;
            foreach (XmlElement xl1 in xmlNodeList)
            {
                if (xl1.GetAttribute("id") == Id.ToString())
                {
                    foreach (XmlElement xl2 in xl1.ChildNodes)
                    {
                        if (xl2.GetAttribute("name") == sName)
                        {
                            xl2.InnerText = sContent;
                        }
                    }
                }                
            }
            //xml.Save(path);
        }
    }
    
    public static void LoadQuestion()
    {
        List<string> lstQuestion = new List<string>();
        List<string> lstAnswer = new List<string>();
        LstQuestions = new List<questions>();
        lstQuestion = GameData.ReadXml("config111.xml", 2, "Q");
        lstAnswer = GameData.ReadXml("config111.xml", 2, "A");
        for (int i = 0; i < lstQuestion.Count; i++)
        {
            string sAnswers = lstAnswer[i];
            string[] sAns = sAnswers.Split(',');
            LstQuestions.Add(new questions(lstQuestion[i], sAns.Length, sAns[0], sAns[1], sAns[2]));            
        }        
    }
    */
    public static void GeneralQuestion(int number)
    {
        qi.LstQuestions = new List<questions>();
        for (int k = 0; k < number; k++)
        {
            int i = Random.Range(1, 8);
            int j = Random.Range(1, 8);
            int a1 = i + j;
            int a2 = a1 + Random.Range(0-a1, -1);
            int a3 = a1 + Random.Range(1, 4);
            
            //GameData.logger("i:" + i + ",j:" + j + ",a1:" + a1 + ",a2:" + a2 + "a3:" + a3, 1);
            
            if (GetRandomRate(0.66f))
            {
                qi.LstQuestions.Add(new questions(i + " + " + j + "= ? ", 2, a1.ToString(), a2.ToString(), a3.ToString()));
                //LstQuestions.Add(new questions("111",3,"1","2","3"));
                //LstI.Add(100);
            }
            else
            {
                //LstI.Add(50);
                //LstQuestions.Add(new questions("111", 3, "1", "2", "3"));
                qi.LstQuestions.Add(new questions(i + " + " + j + "= ? ", 3, a1.ToString(), a2.ToString(), a3.ToString()));
            }
        }
    }

    

    public static bool GetRandomRate(float fRate)
    {
        float f=Random.Range(0f,1.0f);
        if (f <= fRate)
        {
            return true;
        }
        else
        {
            return false;
        }
    }


}

public struct questions
{
    public string sQuestion { get; set; }
    public int iAnswerCount { get; set; }
    public string a1 {get;set;}
    public string a2 { get; set; }
    public string a3 { get; set; }
    public questions(string sQuestion, int iAnswerCount, string a1, string a2, string a3)
    {
        this.sQuestion = sQuestion;
        this.iAnswerCount = iAnswerCount;
        this.a1 = a1;
        this.a2 = a2;
        this.a3 = a3;
    }
}

public struct stairs
{
    public GameObject[] s{get;set;}
    /*s1{get;set;}//左上
    public GameObject s2{get;set;}//右下
    public GameObject s3{get;set;}//左下
    public GameObject s4{get;set;}//右下*/
    public GameObject lastStair { get; set; }//上一个台阶
    public stairs(GameObject[] s, GameObject lastStair)
    {
        this.s = s;
        this.lastStair = lastStair;
    }
}

public struct MsgBox
{
    public string sTitle { get; set; }
    public string sContent { get; set; }
    public string sBtnText { get; set; }
    public float fIsAutoClose { get; set; }
    public MsgBox(string sTitle, string sContent, string sBtnText, float fIsAutoClose)
    {
        this.sTitle = sTitle;
        this.sContent = sContent;
        this.sBtnText = sBtnText;
        this.fIsAutoClose = fIsAutoClose;
    }
}

public struct gameEnv
{
    public Vector3 vBirthPoint { get; set; }
    public float fHorzVal { get; set; }
    public float fVertVal { get; set; }
    public int iStairCount { get; set; }
    public float fHorzMaxVal { get; set; }
    public float fCameraDistinct { get; set; }
    public int iLife { get; set; }
    public gameEnv(Vector3 v, float fH, float fV, int iStairCount, float fHorzMaxVal, float fCameraDistinct,int iLife)
    {
        this.vBirthPoint = v;
        this.fHorzVal = fH;
        this.fVertVal = fV;
        this.iStairCount = iStairCount;
        this.fHorzMaxVal = fHorzMaxVal;
        this.fCameraDistinct = fCameraDistinct;
        this.iLife = iLife;
    }
}